// Kokomi.js - Three.js 组件框架
import * as kokomi from "kokomi.js";
// Three.js - 3D 渲染引擎
import * as THREE from "three";
// three-stdlib - Three.js 标准库（GLTF 加载器）
import * as STDLIB from "three-stdlib";

import type Experience from "../Experience";

// 加速特效的自定义着色器
import speedUpVertexShader from "../Shaders/Speedup/vert.glsl";
import speedUpFragmentShader from "../Shaders/Speedup/frag.glsl";

/**
 * 加速特效组件
 * 显示车辆加速时的速度线效果（类似电影中的运动模糊）
 * 使用自定义着色器实现动态特效
 */
export default class Speedup extends kokomi.Component {
  declare base: Experience; // Experience 实例引用
  model: STDLIB.GLTF; // 加速特效模型
  uj: kokomi.UniformInjector; // Uniform 注入器（自动注入时间等变量）
  material: THREE.ShaderMaterial; // 自定义着色器材质
  
  constructor(base: Experience) {
    super(base);

    // 加载加速特效模型（GLTF 格式）
    const model = this.base.am.items["sm_speedup"] as STDLIB.GLTF;
    this.model = model;

    // 将模型场景树展平为数组
    const modelParts = kokomi.flatModel(model.scene);
    // kokomi.printModel(modelParts); // 可用于调试，打印模型结构

    // 创建 Uniform 注入器，用于自动传递时间、分辨率等变量到着色器
    const uj = new kokomi.UniformInjector(this.base);
    this.uj = uj;
    
    // 创建自定义着色器材质
    const material = new THREE.ShaderMaterial({
      vertexShader: speedUpVertexShader,
      fragmentShader: speedUpFragmentShader,
      transparent: true, // 启用透明
      depthWrite: false, // 禁用深度写入（避免遮挡其他物体）
      uniforms: {
        ...uj.shadertoyUniforms, // 注入 Shadertoy 风格的 uniform（iTime, iResolution 等）
        uSpeed: {
          value: this.base.params.speed, // 当前速度值
        },
        uOpacity: {
          value: this.base.params.speedUpOpacity, // 特效透明度
        },
      },
    });
    this.material = material;

    // 获取模型中的第二个部件（索引 1）作为特效网格
    const speedupMesh = modelParts[1] as THREE.Mesh;
    // 应用自定义着色器材质
    speedupMesh.material = material;
  }
  /**
   * 将加速特效模型添加到场景
   */
  addExisting() {
    this.container.add(this.model.scene);
  }
  /**
   * 每帧更新
   * 更新着色器的 uniform 变量
   */
  update(): void {
    // 注入 Shadertoy 风格的 uniform（时间、分辨率等）
    this.uj.injectShadertoyUniforms(this.material.uniforms);

    // 更新当前速度值到着色器
    this.material.uniforms.uSpeed.value = this.base.params.speed;
  }
}
